using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace OfficeClip.OpenSource.LogShipping
{
    public class Restore
    {
        public static void RestoreDatabase(string dbName, string filePath, string connection)
        {
            OfficeClip.OpenSource.Utility.Db db = new OfficeClip.OpenSource.Utility.Db(connection, Program.Log);
            // If the database is not present the exit
            string errorMessage;
            if (!db.IsDatabasePresent(dbName, out errorMessage))
            {
                Program.Log.WriteError("Database", "Database: " + dbName + " could not be found - " + errorMessage);
                return;
            }
            // While restoring we will need to keep the database in the non-recovery mode till the last file is restored.
            // For the last file we will need to put it back to the recovery mode
            bool isNoRecovery;
            string [] files;
            // check if the database exists, if not come out
            if (Directory.GetFiles(filePath).Length == 0)
            {
                Program.Log.WriteError("Files", "Full backup file not found");
                return;
            }
            files = Directory.GetFiles(filePath);
            string fileName = files[0];
            // if no transaction logs are present then we want to put this database in the recovery mode
            isNoRecovery = (Directory.Exists(filePath + @"\transactionlog") && (Directory.GetFiles(filePath + @"\transactionlog").Length > 0));
            string dbLogicalName = string.Empty;
            string logLogicalName = string.Empty;
            db.GetLogicalNames(ref dbLogicalName, ref logLogicalName, fileName);
            if (OpenSource.Utility.Constants.ErrorMessage != string.Empty)
            {
                Program.Log.WriteError("Database",
                   "Failed to get logical names from:" + fileName + " Error: " + OpenSource.Utility.Constants.ErrorMessage
                   );
                return;
            }
            else
            {
                Program.Log.WriteInfo("Database",
                   "Successfully got logical names: " + dbLogicalName + ", " + logLogicalName);
            }

            string newDbFileName =
             db.GetDatabasePhysicalFileName(dbName);
            if (OpenSource.Utility.Constants.ErrorMessage != string.Empty)
            {
                Program.Log.WriteError("Database",
                   "Could not get the physical file:" + " Error: " + OpenSource.Utility.Constants.ErrorMessage
                   );
                return;
            }
            else
            {
                Program.Log.WriteInfo("Database",
                   "database get physical file name succeeded: " + newDbFileName);
            }
            db.RestoreDatabase(fileName, dbName, newDbFileName, dbLogicalName, logLogicalName, false, true, isNoRecovery, false);
            if (OpenSource.Utility.Constants.ErrorMessage != string.Empty)
            {
                Program.Log.WriteError("Database",
                   "Database restore failed to:" + fileName + " Error: " + OpenSource.Utility.Constants.ErrorMessage
                   );
                return;
            }
            else
            {
                Program.Log.WriteInfo("Database",
                   "database restore succeeded to: " + fileName);
            }
            // if isNoRecovery is true then we will need to go through the transaction logs and recover them
            if (isNoRecovery)
            {
                files = Directory.GetFiles(filePath + @"\transactionlog");
                for (int i = 0; i < files.Length; i++)
                {
                    // for the last item the isNoRecovery will be false
                    if (i == files.Length - 1)
                    {
                        isNoRecovery = false;
                    }
                    db.RestoreTransactionLog(files[i], dbName, isNoRecovery);
                    if (OpenSource.Utility.Constants.ErrorMessage != string.Empty)
                    {
                        Program.Log.WriteError("Database",
                           "Transaction log restore failed from:" + files[i] + " Error: " + OpenSource.Utility.Constants.ErrorMessage
                           );
                        return;
                    }
                    else
                    {
                        Program.Log.WriteInfo("Database","Transaction log restore succeeded from: " + files[i]);
                    }
                }
            }
        }
    }
}
